package cn.wolfcode.wolf2w.interceptor;


import cn.wolfcode.wolf2w.annotation.RequireLogin;
import cn.wolfcode.wolf2w.domain.UserInfo;
import cn.wolfcode.wolf2w.redis.service.IUserInfoRedisService;
import cn.wolfcode.wolf2w.util.JsonResult;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;

/**
 * 用户登录检查
 */
//@Component
public class CheckLoginInterceptor implements HandlerInterceptor{

    @Autowired
    private IUserInfoRedisService userInfoRedisService;

    //请求进入时进行登录拦截
    public  boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //handler 变量是这个HandlerMethod的实例对象
        //HandlerMethod 请求映射方法信息(所在类的信息, 方法信息[映射路径/方法名/参数/注解/返回值...])封装对象
        /**
         *
         * 1: springmvc启动时候,扫描所有的controller类, 解析所有映射方法, 将每个映射方法封装一个对象
         *   HandlerMethod, 该类包含所有请求映射方法信息(映射路径/方法名/参数/注解/返回值...)
         *
         *  2: springmvc针对这些 请求映射方法信息封装对象类 使用类似map的数据结构进行统一管理
         *    Map<String, HandlerMethod>  map = ...
         *       key: 请求映射路径(url)  value就是映射方法信息封装对象类
         *       map.put("/users/currentUser", currentUser这个映射方法对应HandlerMethod实例)
         *       map.put("/users/login", login这个映射方法对应HandlerMethod实例)
         *
         * 3:页面发起请求时(/users/currentUser), 进入拦截器之前, springmvc自动解析请求路径, 得到url(/users/currentUser)
         *    获取url之后,进而获取/users/currentUser  路径对应的映射方法HandlerMethod实例-- handler
         *
         * 4: 调用拦截器 preHandle方法并将请求对象, 响应对象 映射方法对象 handler 一起传入
         *
         */
        //1:如果请求不是动态的, handler对象不是 HandlerMethod 的实例
        //2:如果请求时跨域请求(请求方法是:OPTIONS), handler对象不是 HandlerMethod 的实例

        //解决拦截器跨域
        if(!(handler instanceof HandlerMethod)){
            return true;
        }
        //判断当前请求映射方法头顶是否贴有RequireLogin标签
        HandlerMethod hm = (HandlerMethod) handler;

        String token = request.getHeader("token");
        UserInfo user = userInfoRedisService.getUserByToken(token);

        if (hm.hasMethodAnnotation(RequireLogin.class)) {
            //如果有,需要进行登录检查
            if(user == null){
                //没登录
                response.setContentType("application/json;charset=utf-8");
                response.getWriter().write(JSON.toJSONString(JsonResult.noLogin()));
                return false;
            }
        }
        //如果没有, 直接放行











        return true;
    }
}
